package com.crm.service.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.crm.model.common.dtos.ResponseResult;
import com.crm.model.common.enums.AppHttpCodeEnum;
import com.crm.model.system.dtos.LoginDto;
import com.crm.model.system.pojo.User;
import com.crm.model.system.vos.LoginVo;
import com.crm.service.system.config.RedisCache;
import com.crm.service.system.config.RedisLock;
import com.crm.service.system.mapper.UserMapper;
import com.crm.service.system.properties.JwtProperties;
import com.crm.service.system.service.LoginService;
import com.crm.utils.AliOssUtil;
import com.crm.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import static com.crm.common.constant.StatusConstant.ACCOUNT_DISABLE_STATUS;

@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private RedisLock redisLock;

    private static final String[] OPERATORS = {"+", "-", "*"};
    private static final int WIDTH = 103;
    private static final int HEIGHT = 40;
    private static final int FONT_SIZE = 17;
    private static final int NUM1_RANGE = 20;  // 第一个操作数的取值范围
    private static final int NUM2_RANGE = 20;    // 第二个操作数的取值范围

    @Autowired
    private AliOssUtil aliOssUtil;

    /**
     * 加载图片验证码
     *
     * @return
     */
    @Override
    public ResponseResult load() {
        //生成验证码
        //TODO:验证码防刷
        Map map = generateCaptcha();
        String format = "png";
        byte[] imageBytes = convertToByteArray((BufferedImage) map.get("img"), format);

        String fileName = UUID.randomUUID().toString().replace("-","")+"."+format;

//        String url = aliOssUtil.upload(imageBytes, fileName);
        String url = "https://web-framedevelop.oss-cn-chengdu.aliyuncs.com/0169f70556c54a40a0f6cc7213222c3a.png";
//        redisCache.set(url,map.get("result").toString(),300);
        redisCache.set(url,String.valueOf(224),300);
        return ResponseResult.okResult(url);

    }

    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 登录校验
     * @param loginDto
     * @return
     */
    @Override
    public ResponseResult<LoginVo> login(LoginDto loginDto) {
        //校验数据
        String password = loginDto.getPassword();
        if (loginDto.getAccount().isEmpty() || password.isEmpty() || loginDto.getCaptch() == null || loginDto.getUrl().isEmpty()){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }else {
            if (loginDto.getAccount().length()>11 || password.length()>12 || password.length()<6){
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
            }
        }

        //查询用户
        User user = userMapper.selectOne(
                new LambdaQueryWrapper<User>().eq(User::getAccount,loginDto.getAccount())
        );
        //处理异常情况
        if (user == null){
            //账号不存在
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        //密码比对
        //对前端传过来的明文密码进行md5加密处理
        /*password = DigestUtils.md5DigestAsHex(password.getBytes());*/
        if (!password.equals(user.getPassword())) {
            //密码错误
            return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR);
        }

        //账号状态校验
        if (user.getStatus().equals(ACCOUNT_DISABLE_STATUS)){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_ADMIND);
        }

        //验证码校验
        Boolean isValid = checkCaptch(loginDto.getCaptch(),loginDto.getUrl());
        if (isValid){
            Map<String, Object> claims = new HashMap<>();
            claims.put("userId", user);
            System.out.println(claims.toString());
            String token = JwtUtil.createJWT(
                    jwtProperties.getSecretKey(),
                    jwtProperties.getTtl(),
                    claims);

            LoginVo loginVo = LoginVo.builder()
                    .id(user.getId())
                    .account(user.getAccount())
                    .token(token).build();

            return ResponseResult.okResult(loginVo);
        }

        return ResponseResult.errorResult(AppHttpCodeEnum.ERROR);
    }

    /**
     * 校验验证码
     * @param captch
     * @param url
     * @return
     */
    private Boolean checkCaptch(Integer captch, String url) {
        String s = captch.toString();
        return redisCache.get(url).equals(s);
    }


    /**
     * 生成图片验证码
     * @return
     */
    private Map generateCaptcha() {
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = image.getGraphics();

        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, WIDTH, HEIGHT);

        Random random = new Random();

        while (true){
            // 随机生成算式
            int num1 = random.nextInt(NUM1_RANGE);
            int num2 = random.nextInt(NUM2_RANGE);
            String operator = OPERATORS[random.nextInt(OPERATORS.length)];
            Integer result = 0;

            // 根据运算符计算结果
            switch (operator) {
                case "+":
                    result = num1 + num2;
                    break;
                case "-":
                    result = num1 - num2;
                    break;
                case "*":
                    result = num1 * num2;
                    break;
            /*case "/":
                result = num1 / num2;
                break;*/
            }

            if (result > 0){
                String equation = num1 + " " + operator + " " + num2 + " = ";

                // 绘制算式
                graphics.setFont(new Font("Arial", Font.BOLD, FONT_SIZE));
                graphics.setColor(Color.BLACK);
                graphics.drawString(equation, 10, HEIGHT / 2 + 15);

                graphics.dispose();

                //BufferedImage类装File类
                /*File image = saveImage(image);*/
                Map<String,Object> captch = new HashMap();
                captch.put("img",image);
                captch.put("result",result);
                return captch;
            }
        }
    }

    /**
     * BufferedImage转换成字节数组
     * @param image
     * @param format
     * @return
     */
    private byte[] convertToByteArray(BufferedImage image, String format) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        try {
            ImageIO.write(image, format, baos);
            baos.flush();
        } catch (IOException e) {
            log.info("转换图像失败：" + e.getMessage());

        } finally {
            try {
                baos.close();
            } catch (IOException e) {
                log.info("关闭 ByteArrayOutputStream 失败：" + e.getMessage());
            }
        }
        return baos.toByteArray();
    }


}
